﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace SPVisualDev.Services
{
    public class ContentTypes
    {
        public const string C_MS_SHAREPOINT_XMLNS = "http://schemas.microsoft.com/sharepoint/";
        public const string C_MS_SHAREPOINT_EVENTS_NS = "http://schemas.microsoft.com/sharepoint/events";

        public static string GetContentTypeGroups(string Url)
        {
            XmlDocument OwnerDocument = new XmlDocument();

            XmlElement parent_node = OwnerDocument.CreateElement("ContentTypeGroups");

            using (SPSite site = new SPSite(Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPContentTypeCollection coll = web.ContentTypes;
                    List<string> list = new List<string>();

                    foreach (SPContentType ct in coll)
                    {
                        if (!list.Contains(ct.Group))
                            list.Add(ct.Group);
                    }

                    foreach (string s in list)
                    {
                        XmlElement el = OwnerDocument.CreateElement("Group");
                        el.SetAttribute("Name", s);
                        parent_node.AppendChild(el);
                    }
                }
            }

            return parent_node.OuterXml;
        }

        public static string GetContentTypesByGroup(string Url, string Group)
        {
            XmlDocument OwnerDocument = new XmlDocument();

            XmlElement parent_node = OwnerDocument.CreateElement("ContentTypes");

            using (SPSite site = new SPSite(Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPContentTypeCollection coll = web.ContentTypes;
                    List<SPContentType> list = new List<SPContentType>();

                    foreach (SPContentType ct in coll)
                    {
                        if (ct.Group == Group && !list.Contains(ct))
                            list.Add(ct);
                    }

                    foreach (SPContentType ct in list)
                    {
                        XmlElement el = OwnerDocument.CreateElement("ContentType");
                        el.SetAttribute("Id", ct.Id.ToString());
                        el.SetAttribute("Name", ct.Name);
                        parent_node.AppendChild(el);
                    }
                }
            }

            return parent_node.OuterXml;
        }

        public static string GetContentTypesData(string Url, string Name)
        {
            XmlDocument OwnerDocument = new XmlDocument();

            XmlElement parent_node = OwnerDocument.CreateElement("ContentTypeData");

            using (SPSite site = new SPSite(Url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPContentType ct = web.ContentTypes[Name];
                    XmlElement ImportedXml = OwnerDocument.CreateElement("ContentType", C_MS_SHAREPOINT_XMLNS);

                    ImportedXml.SetAttribute("ID", ct.Id.ToString());
                    ImportedXml.SetAttribute("Name", ct.Name);
                    ImportedXml.SetAttribute("Description", ct.Description);
                    ImportedXml.SetAttribute("Group", ct.Group);

                    SPContentType ct_parent = ct.Parent;
                    Hashtable remove_fields = new Hashtable();

                    if (ct_parent != null)
                    {
                        while (ct_parent.Name != "System")
                        {
                            foreach (SPField fld in ct_parent.Fields)
                                if (!remove_fields.ContainsKey(fld.Id))
                                    remove_fields.Add(fld.Id, true);

                            ct_parent = ct_parent.Parent;

                        }
                    }

                    List<XmlElement> fields_to_add = new List<XmlElement>();
                    XmlElement xe_fieldrefs = OwnerDocument.CreateElement("FieldRefs", C_MS_SHAREPOINT_XMLNS);

                    foreach (SPField fld in ct.Fields)
                    {
                        if (remove_fields.ContainsKey(fld.Id))
                            continue;

                        XmlElement xe_fieldref = OwnerDocument.CreateElement("FieldRef", C_MS_SHAREPOINT_XMLNS);
                        xe_fieldref.SetAttribute("ID", fld.Id.ToString());
                        xe_fieldref.SetAttribute("Name", fld.InternalName);

                        xe_fieldrefs.AppendChild(xe_fieldref);

                        XmlDocument field_schema_xml = new XmlDocument();
                        field_schema_xml.LoadXml(fld.SchemaXml);

                        XmlElement new_field_xml = OwnerDocument.CreateElement("Field", C_MS_SHAREPOINT_XMLNS);
                        foreach (XmlAttribute attr in field_schema_xml.DocumentElement.Attributes)
                        {
                            if (attr.Name == "Customization" ||
                                attr.Name == "Version")
                                continue;

                            new_field_xml.SetAttribute(attr.Name, attr.Value);
                        }

                        fields_to_add.Add(new_field_xml);

                    }

                    ImportedXml.AppendChild(xe_fieldrefs);

                    parent_node.AppendChild(ImportedXml);



                    XmlElement el = OwnerDocument.CreateElement("Fields");
                    foreach (XmlElement el2 in fields_to_add)
                    {
                        el.AppendChild(el2);
                    }

                    parent_node.AppendChild(el);

                }
            }

            return parent_node.OuterXml;
        }

        public static string GetAllBuiltInContentTypes()
        {
            XmlDocument OwnerDocument = new XmlDocument();

            XmlElement parent_node = OwnerDocument.CreateElement("ContentTypes");

            SPFeatureDefinition def = SPFarm.Local.FeatureDefinitions["ctypes"];
            foreach (SPElementDefinition element in def.GetElementDefinitions(System.Globalization.CultureInfo.CurrentCulture))
            {
                if (element.ElementType == "ContentType")
                {
                    XmlElement el = OwnerDocument.CreateElement("ContentType");
                    el.SetAttribute("Name", Common.GetXmlAttribute(element.XmlDefinition as XmlElement, "Name"));
                    el.SetAttribute("Id", Common.GetXmlAttribute(element.XmlDefinition as XmlElement, "ID"));
                    parent_node.AppendChild(el);
                }
            }


            return parent_node.OuterXml;
        }
    }
}
